<

Flutter でのエラーの処理

Flutter フレームワークはコールバック中に発生するエラーをキャッチします 発生したエラーを含む、フレームワーク自体によってトリガーされる 構築、レイアウト、ペイントの段階で。発生しないエラー Flutter のコールバック内ではフレームワークによって捕捉できません。 ただし、エラーハンドラを設定することでそれらを処理できます。PlatformDispatcher

Flutter によって捕捉されたすべてのエラーは、FlutterError.onErrorハンドラ。デフォルトでは、 これは電話しますFlutterError.presentError、 これにより、エラーがデバイス ログにダンプされます。 IDE から実行する場合、インスペクターはこれをオーバーライドします。 動作を変更して、エラーも IDE にルーティングできるようにする コンソールを使用して、 メッセージに記載されているオブジェクト。

ビルド段階でエラーが発生した場合、 のErrorWidget.builderコールバックは 使用されるウィジェットを構築するために呼び出されます 失敗したものの代わりに。デフォルトでは、 デバッグモードではエラーメッセージが赤色で表示されます。 リリース モードでは、灰色の背景が表示されます。

コールスタックに Flutter コールバックがない状態でエラーが発生した場合、 それらはによって扱われますPlatformDispatcherのエラー コールバック。デフォルトでは、 これはエラーを出力するだけで、他には何も行いません。

これらの動作をカスタマイズできます。 通常は、それらを次の値に設定します。 あなたのvoid main()関数。

以下に各エラーの種類の処理について説明します。一番下に あらゆる種類のエラーを処理するコード スニペットがあります。平 スニペットをコピーして貼り付けることもできますが、次のことをお勧めします。 まず、各エラーの種類について理解します。

Flutter によってキャッチされたエラー

たとえば、アプリケーションをいつでもすぐに終了できるようにするには、 エラーはリリースモードの Flutter によってキャッチされるため、 次のハンドラ:

import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

void main() {
  FlutterError.onError = (details) {
    FlutterError.presentError(details);
    if (kReleaseMode) exit(1);
  };
  runApp(const MyApp());
}

// rest of `flutter create` code...

このハンドラーは、ログ サービスにエラーを報告するために使用することもできます。 詳細については、クックブックの章を参照してください。サービスにエラーを報告する

ビルドフェーズエラー用のカスタムエラーウィジェットを定義する

いつでも表示されるカスタマイズされたエラー ウィジェットを定義するには ビルダーがウィジェットの構築に失敗した場合は、次を使用します。MaterialApp.builder

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, widget) {
        Widget error = const Text('...rendering error...');
        if (widget is Scaffold || widget is Navigator) {
          error = Scaffold(body: Center(child: error));
        }
        ErrorWidget.builder = (errorDetails) => error;
        if (widget != null) return widget;
        throw ('widget is null');
      },
    );
  }
}

Flutter でキャッチされないエラー

考えてみましょうonPressed非同期関数を呼び出すコールバック、 そのようなMethodChannel.invokeMethod(またはほとんどすべてのプラグイン)。 例えば:

OutlinedButton(
  child: const Text('Click me!'),
  onPressed: () async {
    const channel = MethodChannel('crashy-custom-channel')
    await channel.invokeMethod('blah')
  },
)

もしもinvokeMethodエラーがスローされるため、転送されませんFlutterError.onError。 代わりに、に転送されます。PlatformDispatcher

このようなエラーを捕捉するには、次を使用しますPlatformDispatcher.instance.onError

import 'package:flutter/material.dart';
import 'dart:ui';

void main() {
  MyBackend myBackend = MyBackend();
  PlatformDispatcher.instance.onError = (error, stack) {
    myBackend.sendError(error, stack);
    return true;
  };
  runApp(const MyApp());
}

あらゆる種類のエラーの処理

例外が発生したときにアプリケーションを終了し、次のメッセージを表示したいとします。 ウィジェットの構築が失敗するたびにカスタム エラー ウィジェット - ベースにすることができます 次のコードスニペットでのエラー処理:

import 'package:flutter/material.dart';
import 'dart:ui';

Future<void> main() async {
  await myErrorsHandler.initialize();
  FlutterError.onError = (details) {
    FlutterError.presentError(details);
    myErrorsHandler.onErrorDetails(details);
  };
  PlatformDispatcher.instance.onError = (error, stack) {
    myErrorsHandler.onError(error, stack);
    return true;
  };
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, widget) {
        Widget error = const Text('...rendering error...');
        if (widget is Scaffold || widget is Navigator) {
          error = Scaffold(body: Center(child: error));
        }
        ErrorWidget.builder = (errorDetails) => error;
        if (widget != null) return widget;
        throw ('widget is null');
      },
    );
  }
}